﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections;
using System.Web;
using Medianamik.Core;
using Medianamik.Core.Interfaces;
using System.Globalization;
using System.Collections.ObjectModel;
using System.Xml.Linq;
using Medianamik.Core.Lock;

namespace Medianamik.UI.Lock
{
    public class Transaction
    {

        internal static string COOKIE_NAME = "mkLock";
        //private TimeSpan  _period = TimeSpan.FromSeconds(10); //Default value
        //private DateTime _activationDate;
        //private XElement _userInfo;
        private Guid _id;
        //private TimeSpan  _timeBuffer = TimeSpan.FromSeconds(100);

        public Transaction()
        {
            //_userInfo = userInfo;
            InitTransacCookie();
        }

        internal Transaction(Guid transacId)
        {
            _id = transacId;
            //_userInfo = userInfo;
            //_activationDate = activationDate;
        }

        public void Lock(Guid pObjectId, TimeSpan pUltimatum, string pUserName)
        {
            if (!LockManager.IsLocked(pObjectId))
            {
                LockManager.CreateLock(_id, pObjectId, pUltimatum, pUserName);

            }
            else
            {
                //L'item est déjà verrouillé!
                throw new ArgumentException("Item already locked");
            }
        }

        //private Collection<LockNode> _locks;
        //public  Collection<LockNode> Locks 
        //{
        //    get
        //    {
        //        return _locks ?? (_locks = LockManager.GetLocks(_id));
        //    }
        //}


        //public void Commit()
        //{
        //    HttpContext.Current.Response.Cookies.Remove(COOKIE_NAME);
        //    LockManager.DeleteTransaction(_id);
        //}

        public void Unlock(Guid pObjectId)
        {
            LockManager.UnlockObject(pObjectId);
        }

        private void InitTransacCookie()
        {
            _id = Guid.NewGuid();
            HttpCookie c = HttpContext.Current.Request.Cookies[COOKIE_NAME];
            if (c == null) { c = new HttpCookie(COOKIE_NAME); }
            c["uId"] = _id.ToString();
            c["activationDate"] = string.Empty;
            c.Path = "/";
            HttpContext.Current.Response.Cookies.Add(c);
        }

        private void SetTransacCookieValue(string key, string value)
        {
            HttpCookie c = HttpContext.Current.Request.Cookies[COOKIE_NAME];
            if (c == null) { throw new ArgumentException("Aucun cookie de transaction n'existe. Source : SetTransacCookieValue"); }
            c[key] = value;
            HttpContext.Current.Response.Cookies.Add(c);
        }

        //public LockStatus  Activate( )
        //{

        //    //on s'assure que la transaction peut être activer
        //    //en vérifiant qu'aucune autre transaction en cours 
        //    //d'activation tente de verrouiller les même ids.

        //    if (LockManager.ActivateTransaction(_id, _period))
        //    {
        //        SetTransacCookieValue("activationDate", DateTime.Now.ToString(CultureInfo.InvariantCulture));
        //        return LockStatus.KeepAlive;
        //    }
        //    else
        //    {
        //        LockManager.DeleteTransaction(_id);
        //        return LockStatus.Elapsed;
        //    }

        //}

        public LockStatus KeepAlive(Guid pObjectId)
        {

            var locks = LockManager.GetLocksByObjectId(pObjectId);
            var currentLock = locks.FirstOrDefault(l => l.Transaction == _id && !l.IsElapsed());

            if (currentLock != null)
            {
                LockManager.UpdateLock(currentLock);
                return LockStatus.KeepAlive;
            }
            else return LockStatus.Elapsed;

        }

        //public bool IsActivated
        //{
        //    get
        //    {
        //        if( _activationDate.Equals(DateTime.MinValue)) { return false;}
        //        return true;
        //    }
        //}
    }
}
